home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / nroff~06.zoo / escape.c < prev    next >
C/C++ Source or Header  |  1992-07-16  |  23KB  |  1,227 lines

  1. static char *rcsid_escape_c="$Id: escape.c,v 1.2 1992/07/16 10:38:32 rosenkra Exp $";
  2.  
  3. /*
  4.  * $Log: escape.c,v $
  5.  * Revision 1.2  1992/07/16  10:38:32  rosenkra
  6.  * port to gcc, add tm,ie,el
  7.  *
  8.  */
  9.  
  10. /*
  11.  *    escape.c - Escape and special character input processing portion of
  12.  *               nroff word processor
  13.  *
  14.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  15.  *    net:    rosenkra@convex.com
  16.  *    CIS:    71460,17
  17.  *    GENIE:    W.ROSENKRANZ
  18.  *
  19.  *    original author:
  20.  *
  21.  *    Stephen L. Browning
  22.  *    5723 North Parker Avenue
  23.  *    Indianapolis, Indiana 46220
  24.  *
  25.  *    history:
  26.  *
  27.  *    - Originally written in BDS C;
  28.  *    - Adapted for standard C by W. N. Paul
  29.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  30.  */
  31.  
  32. #undef NRO_MAIN                    /* extern globals */
  33.  
  34. #include <stdio.h>
  35. #include "nroff.h"
  36.  
  37.  
  38. /*------------------------------*/
  39. /*    expesc            */
  40. /*------------------------------*/
  41. void expesc (p, q)
  42. char   *p;
  43. char   *q;
  44. {
  45.  
  46. /*
  47.  *    Expand escape sequences
  48.  */
  49.  
  50.     REGISTER char  *s;
  51.     REGISTER char  *t;
  52.     REGISTER char  *pstr;
  53.     REGISTER int    i;
  54.     REGISTER int    val;
  55.     REGISTER int    autoinc;
  56.     char        c;
  57.     char        fs[20];                /* for font change */
  58.     char        nrstr[20];
  59.     char        fmt[20];
  60.     char        name[10];
  61.     int        nreg;
  62.     char           *pfs;
  63.     int        inc;
  64.     int        tmp;
  65.     char        delim;
  66.  
  67.  
  68.     s = p;
  69.     t = q;
  70.  
  71.  
  72.     /*
  73.      *   if escape parsing is not on, just copy string
  74.      */
  75.     if (dc.escon == NO)
  76.     {
  77.         while (*s != EOS)
  78.         {
  79.             *t++ = *s++;
  80.         }
  81.         *t = EOS;
  82.         strcpy (p, q);
  83.  
  84.         return;
  85.     }
  86.  
  87.  
  88.     /*
  89.      *   do it...
  90.      */
  91.     while (*s != EOS)
  92.     {
  93.         if (*s != dc.escchr)
  94.         {
  95.             /*
  96.              *   not esc, continue...
  97.              */
  98.             *t++ = *s++;
  99.         }
  100.  
  101.  
  102.         else if (*(s + 1) == dc.escchr)
  103.         {
  104.             /*
  105.              *   \\            escape escape
  106.              */
  107.             *t++ = *s++;
  108.             ++s;
  109.         }
  110.  
  111.  
  112.         else if (*(s + 1) == 'n')
  113.         {
  114.             /*
  115.              *   \nx, \n(xx        register
  116.              *
  117.              *   first check for \n+... or \n-... (either form)
  118.              */
  119.             s += 2;
  120.             autoinc = 0;
  121.             if (*s == '+')
  122.             {
  123.                 autoinc = 1;
  124.                 s += 1;
  125.             }
  126.             if (*s == '-')
  127.             {
  128.                 autoinc = -1;
  129.                 s += 1;
  130.             }
  131.  
  132.  
  133.  
  134.             /*
  135.              *   was this \nx or \n(xx form?
  136.              */
  137.             if (isalpha (*s))
  138.             {
  139.                 /*
  140.                  *   \nx form. find reg (a-z)
  141.                  */
  142.                 nreg = tolower (*s) - 'a';
  143.  
  144.  
  145.                 /*
  146.                  *   was this \n+x or \n-x? if so, do the
  147.                  *   auto incr
  148.                  */
  149.                 if (autoinc > 0)
  150.                     dc.nr[nreg] += dc.nrauto[nreg];
  151.                 else if (autoinc < 0)
  152.                     dc.nr[nreg] -= dc.nrauto[nreg];
  153.  
  154.                 /*
  155.                  *   display format
  156.                  */
  157.                 if (dc.nrfmt[nreg] == '1')
  158.                 {
  159.                     /*
  160.                      *   normal decimal digits
  161.                      */
  162.                     t += itoda (dc.nr[nreg], t, 6) - 1;
  163.                 }
  164.                 else if (dc.nrfmt[nreg] == 'i')
  165.                 {
  166.                     /*
  167.                      *   lower roman
  168.                      */
  169.                     t += itoroman (dc.nr[nreg], t, 24) - 1;
  170.                 }
  171.                 else if (dc.nrfmt[nreg] == 'I')
  172.                 {
  173.                     /*
  174.                      *   upper roman
  175.                      */
  176.                     t += itoROMAN (dc.nr[nreg], t, 24) - 1;
  177.                 }
  178.                 else if (dc.nrfmt[nreg] == 'a')
  179.                 {
  180.                     /*
  181.                      *   lower letters
  182.                      */
  183.                     t += itoletter (dc.nr[nreg], t, 12) - 1;
  184.                 }
  185.                 else if (dc.nrfmt[nreg] == 'A')
  186.                 {
  187.                     /*
  188.                      *   upper letters
  189.                      */
  190.                     t += itoLETTER (dc.nr[nreg], t, 12) - 1;
  191.                 }
  192.                 else if (dc.nrfmt[nreg] & 0x80)
  193.                 {
  194.                     /*
  195.                      *   zero-filled decimal
  196.                      */
  197.                     sprintf (fmt, "%%0%dld",
  198.                         (int)(dc.nrfmt[nreg] & 0x7F));
  199.                     fmt[5] = '\0';
  200.                     sprintf (nrstr, fmt, (long) dc.nr[nreg]);
  201.                     tmp = dc.nrfmt[nreg] & 0x7F;
  202.                     nrstr[tmp] = '\0';
  203.  
  204.                     strcpy (t, nrstr);
  205.                     t += strlen (nrstr);
  206.                 }
  207.                 else
  208.                 {
  209.                     /*
  210.                      *   normal (default)
  211.                      */
  212.                     t += itoda (dc.nr[nreg], t, 6) - 1;
  213.                 }
  214.                 ++s;
  215.             }
  216.             else if (*s == '%')
  217.             {
  218.                 /*
  219.                  *   \n% form. find index into reg struct
  220.                  */
  221.                 nreg = findreg ("%");
  222.                 if (nreg < 0)
  223.                 {
  224.                     fprintf (err_stream,
  225.                         "***%s: no register match (%%)\n",
  226.                         myname);
  227.                     err_exit (-1);
  228.                 }
  229.  
  230.  
  231.                 /*
  232.                  *   was this \n+% or \n-%? if so, do the
  233.                  *   auto incr
  234.                  */
  235.                 if (autoinc > 0)
  236.                     rg[nreg].rval += rg[nreg].rauto;
  237.                 else if (autoinc < 0)
  238.                     rg[nreg].rval -= rg[nreg].rauto;
  239.  
  240.  
  241.                 /*
  242.                  *   display format
  243.                  */
  244.                 if (rg[nreg].rfmt == '1')
  245.                 {
  246.                     /*
  247.                      *   normal decimal digits
  248.                      */
  249.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  250.                 }
  251.                 else if (rg[nreg].rfmt == 'i')
  252.                 {
  253.                     /*
  254.                      *   lower roman
  255.                      */
  256.                     t += itoroman (rg[nreg].rval, t, 24) - 1;
  257.                 }
  258.                 else if (rg[nreg].rfmt == 'I')
  259.                 {
  260.                     /*
  261.                      *   upper roman
  262.                      */
  263.                     t += itoROMAN (rg[nreg].rval, t, 24) - 1;
  264.                 }
  265.                 else if (rg[nreg].rfmt == 'a')
  266.                 {
  267.                     /*
  268.                      *   lower letters
  269.                      */
  270.                     t += itoletter (rg[nreg].rval, t, 12) - 1;
  271.                 }
  272.                 else if (rg[nreg].rfmt == 'A')
  273.                 {
  274.                     /*
  275.                      *   upper letters
  276.                      */
  277.                     t += itoLETTER (rg[nreg].rval, t, 12) - 1;
  278.                 }
  279.                 else if (rg[nreg].rfmt & 0x80)
  280.                 {
  281.                     /*
  282.                      *   zero-filled decimal
  283.                      */
  284.                     sprintf (fmt, "%%0%dld",
  285.                         (int)(rg[nreg].rfmt & 0x7F));
  286.                     fmt[5] = '\0';
  287.                     sprintf (nrstr, fmt, (long) rg[nreg].rval);
  288.                     tmp = rg[nreg].rfmt & 0x7F;
  289.                     nrstr[tmp] = '\0';
  290.  
  291.                     strcpy (t, nrstr);
  292.                     t += strlen (nrstr);
  293.                 }
  294.                 else
  295.                 {
  296.                     /*
  297.                      *   normal (default)
  298.                      */
  299.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  300.                 }
  301.                 s += 1;
  302.             }
  303.             else if (*s == '(')
  304.             {
  305.                 /*
  306.                  *   \n(xx form. find index into reg struct
  307.                  */
  308.                 s += 1;
  309.                 name[0] = *s;
  310.                 name[1] = *(s + 1);
  311.                 if (name[1] == ' '  || name[1] == '\t'
  312.                 ||  name[1] == '\n' || name[1] == '\r')
  313.                     name[1] = '\0';
  314.                 name[2] = '\0';
  315.                 nreg = findreg (name);
  316.                 if (nreg < 0)
  317.                 {
  318.                     fprintf (err_stream,
  319.                         "***%s: no register match (%s)\n",
  320.                         myname, name);
  321.                     err_exit (-1);
  322.                 }
  323.                 
  324.  
  325.                 /*
  326.                  *   was this \n+(xx or \n-(xx? if so, do the
  327.                  *   auto incr
  328.                  */
  329.                 if (rg[nreg].rflag & RF_WRITE)
  330.                 {
  331.                     if (autoinc > 0)
  332.                         rg[nreg].rval += rg[nreg].rauto;
  333.                     else if (autoinc < 0)
  334.                         rg[nreg].rval -= rg[nreg].rauto;
  335.                 }
  336.  
  337.  
  338.                 /*
  339.                  *   display format
  340.                  */
  341.                 if (rg[nreg].rfmt == '1')
  342.                 {
  343.                     /*
  344.                      *   normal decimal digits
  345.                      */
  346.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  347.                 }
  348.                 else if (rg[nreg].rfmt == 'i')
  349.                 {
  350.                     /*
  351.                      *   lower roman
  352.                      */
  353.                     t += itoroman (rg[nreg].rval, t, 24) - 1;
  354.                 }
  355.                 else if (rg[nreg].rfmt == 'I')
  356.                 {
  357.                     /*
  358.                      *   upper roman
  359.                      */
  360.                     t += itoROMAN (rg[nreg].rval, t, 24) - 1;
  361.                 }
  362.                 else if (rg[nreg].rfmt == 'a')
  363.                 {
  364.                     /*
  365.                      *   lower letters
  366.                      */
  367.                     t += itoletter (rg[nreg].rval, t, 12) - 1;
  368.                 }
  369.                 else if (rg[nreg].rfmt == 'A')
  370.                 {
  371.                     /*
  372.                      *   upper letters
  373.                      */
  374.                     t += itoLETTER (rg[nreg].rval, t, 12) - 1;
  375.                 }
  376.                 else if (rg[nreg].rfmt & 0x80)
  377.                 {
  378.                     /*
  379.                      *   zero-filled decimal
  380.                      */
  381.                     sprintf (fmt, "%%0%dld",
  382.                         (int)(rg[nreg].rfmt & 0x7F));
  383.                     fmt[5] = '\0';
  384.                     sprintf (nrstr, fmt, (long) rg[nreg].rval);
  385.                     tmp = rg[nreg].rfmt & 0x7F;
  386.                     nrstr[tmp] = '\0';
  387.  
  388.                     strcpy (t, nrstr);
  389.                     t += strlen (nrstr);
  390.                 }
  391.                 else
  392.                 {
  393.                     /*
  394.                      *   normal (default)
  395.                      */
  396.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  397.                 }
  398.                 s += 2;
  399.             }
  400.         }
  401.  
  402.  
  403.         else if (*(s + 1) == '\"')
  404.         {
  405.             /*
  406.              *   \"            comment
  407.              */
  408.             *s = EOS;
  409.             *t = *s;
  410.  
  411.             return;
  412.         }
  413.  
  414.  
  415.         else if (*(s + 1) == '*')
  416.         {
  417.             /*
  418.              *   \*x, \*(xx        string
  419.              */
  420.             s += 2;
  421.             if (*s == '(')
  422.             {
  423.                 /*
  424.                  *   \*(xx form
  425.                  */
  426.                 s += 1;
  427.                 name[0] = *s;
  428.                 name[1] = *(s + 1);
  429.                 name[2] = '\0';
  430.                 pstr = getstr (name);
  431.                 if (!pstr)
  432.                 {
  433.                     fprintf (err_stream,
  434.                         "***%s: string not found (\\*(%s)\n",
  435.                         myname, name);
  436.                     err_exit (-1);
  437.                 }
  438.                 while (*pstr)
  439.                     *t++ = *pstr++;
  440.                 s += 2;
  441.             }
  442.             else
  443.             {
  444.                 /*
  445.                  *   \*x form
  446.                  */
  447.                 name[0] = *s;
  448.                 name[1] = '\0';
  449.                 pstr = getstr (name);
  450.                 if (!pstr)
  451.                 {
  452.                     fprintf (err_stream,
  453.                         "***%s: string not found (\\*%s)\n",
  454.